package com.bangwz.handler;

import java.nio.ByteBuffer;

import org.tio.core.Aio;
import org.tio.core.ChannelContext;
import org.tio.core.GroupContext;
import org.tio.core.exception.AioDecodeException;
import org.tio.core.intf.Packet;
import org.tio.server.intf.ServerAioHandler;

import com.bangwz.log.PrintLog;
import com.bangwz.pack.MyPacket;

public class MyServerAIOHandler implements ServerAioHandler {

	/**
	 * 解码
	 */
	@Override
	public Packet decode(ByteBuffer buffer, ChannelContext channelContext) throws AioDecodeException {
		// 读取到的总包长度
		int readableLength = buffer.limit() - buffer.position();
		// 收到的数据包小于我的包头长度，返回null
		if (readableLength < MyPacket.HEAD_LENTH)
			return null;
		// 消息体长度
		int bodyLength = buffer.getInt();
		if (bodyLength < 0)
			throw new AioDecodeException(
					"bodyLength [" + bodyLength + "] is not right, remote:" + channelContext.getClientNode());

		// 计算本次需要的数据长度
		int neededLength = MyPacket.HEAD_LENTH + bodyLength;
		// 收到的数据包是否足够组包
		int dataLength = readableLength - neededLength;
		if (dataLength < 0)
			return null;
		else {
			MyPacket myPacket = new MyPacket();
			if (bodyLength > 0) {
				byte[] ret = new byte[bodyLength];
				buffer.get(ret);
				myPacket.setBody(ret);
			}
			return myPacket;
		}
	}

	/**
	 * 编码
	 */
	@Override
	public ByteBuffer encode(Packet packet, GroupContext groupContext, ChannelContext channelContext) {
		MyPacket myPacket = (MyPacket) packet;
		byte[] body = myPacket.getBody();
		int bodyLength = 0;
		if (body != null) {
			bodyLength = body.length;
		}
		// bytebuffer的总长度是 = 消息头的长度 + 消息体的长度
		int allLength = MyPacket.HEAD_LENTH + bodyLength;
		ByteBuffer byteBuffer = ByteBuffer.allocate(allLength);
		// 设置字节序
		byteBuffer.order(groupContext.getByteOrder());
		// 写入消息头
		byteBuffer.putInt(bodyLength);
		// 写入消息体
		if (body != null) {
			byteBuffer.put(body);
		}
		return byteBuffer;
	}

	/**
	 * 处理
	 */
	@Override
	public void handler(Packet packet, ChannelContext channelContext) throws Exception {
		MyPacket myPacket = (MyPacket) packet;
		byte[] body = myPacket.getBody();
		if (null != body) {
			String str = new String(body, MyPacket.CHARSET);
			PrintLog.log("服务器收到消息：" + str);
			// 设置消息返回
			MyPacket reponse = new MyPacket();
			reponse.setBody(("你好客户端，我是服务器" + str).getBytes(MyPacket.CHARSET));
			Aio.send(channelContext, reponse);
		}
	}

}
